package cn.kpt.auth.controller;

import cn.kpt.auth.service.TokenService;
import cn.kpt.auth.service.UserService;
import cn.kpt.beans.dto.Dto;
import cn.kpt.beans.pojo.ItripUser;
import cn.kpt.beans.vo.ItripTokenVO;
import cn.kpt.utils.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.Date;

/**
 * @version 1.0
 * @ClassName LoginController
 * @Description TODO
 * @Author kangpengtao
 * @Date 2019/9/28 17:04
 */
@Api(tags = "登录控制器")
@RestController
@RequestMapping("/api")
public class LoginController {
    @Resource
    private UserService userService;
    @Resource
    private TokenService tokenService;
    @Resource
    private ValidationToken validationToken;

    /**
     * 自注册用户登录
     */
    @ApiOperation(value = "用户登录",
            notes = "手机用户激活成功后进行登录。<br/>" +
                    "成功：success='true' | 失败：success='false' 且返回错误代码，错误码如下：<br/>" +
                    "<ul>" +
                    "<li>300003：手机号格式错误</li>" +
                    "<li>300008：用户还激活，请先激活</li>" +
                    "<li>300000：登录失败，请重试</li>" +
                    "</ul>",
            produces = "application/json;charset=UTF-8")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "name", value = "用户名", required = true, paramType = "query"),
            @ApiImplicitParam(name = "password", value = "密码", required = true, paramType = "query"),
            @ApiImplicitParam(name = "userAgent", value = "token 信息", required = true, paramType = "query")

    })
    @RequestMapping(value = "/dologin", method = RequestMethod.POST)
//    @RequestHeader("User-Agent")请求头 使用者信息
    public Dto dologin(@RequestParam String name, @RequestParam String password, @RequestHeader("User-Agent") String userAgent) {
        try {
//            登录先表单验证
            if (!ValidateUtil.validPhone(name) && !ValidateUtil.validEmail(name)) {
                return DtoUtil.returnFail("手机号格式错误", ErrorCode.AUTH_PARAMETER_ERROR);
            }
//            验证密码
            ItripUser itripUser = userService.login(name, password);
            if (EmptyUtils.isEmpty(itripUser)) {
                return DtoUtil.returnFail("用户名或者密码错误", ErrorCode.AUTH_PARAMETER_ERROR);
            } else {
                //检测是否激活
                if (itripUser.getActivated() == 0) {
                    return DtoUtil.returnFail("用户还激活，请先激活", ErrorCode.AUTH_USER_NEED_ACTIVATE);
                }
            }
//            登录成功，使用Token存储用户信息
            String token = tokenService.genToken(itripUser, userAgent);
//             保存token，保证唯一
            tokenService.saveToken(token, itripUser, userAgent);
            ItripTokenVO itripTokenVO = new ItripTokenVO(token, new Date().getTime() + TokenService.TOKEN_TIME_OUT * 1000, new Date().getTime());
            return DtoUtil.returnDataSuccess(itripTokenVO);
        } catch (Exception e) {
            e.printStackTrace();
            return DtoUtil.returnFail("登录失败，请重试", ErrorCode.AUTH_UNKNOWN);
        }
    }

    /**
     * 置换token
     *
     * @return
     */
    @RequestMapping(value = "/retoken", method = RequestMethod.POST)
    public Dto retoken(@RequestHeader String token, @RequestHeader("User-Agent") String userAgent) {
        try {
//            token 验证
            ItripUser currentUser = validationToken.getCurrentUser(TokenService.TOKEN_KEY + token);
            if (EmptyUtils.isEmpty(currentUser)) {
                return DtoUtil.returnFail("用户未登录或者token已过期", ErrorCode.AUTH_TOKEN_INVALID);
            }
            //token 在半小时后进行置换（）登录时间更新
            if (!tokenService.checkTokenTimeOut(token, userAgent)) {
                return DtoUtil.returnFail("", ErrorCode.AUTH_RETOKEN_NEED_WAIT);
            }
            //token进行置换（将信息更换并存储旧信息）
            String newToken = tokenService.refreshToken(token, userAgent, currentUser);
//           新的信息生成
            ItripTokenVO itripTokenVO = new ItripTokenVO(newToken, new Date().getTime() + TokenService.TOKEN_TIME_OUT * 1000, new Date().getTime());
            return DtoUtil.returnDataSuccess(itripTokenVO);
        } catch (Exception e) {
            e.printStackTrace();
            return DtoUtil.returnFail("置换token失败", ErrorCode.AUTH_UNKNOWN);
        }
    }

    /**
     * 注销
     *
     * @return
     */
    @RequestMapping(value = "/logout", method = RequestMethod.GET)
    public Dto logout(@RequestHeader String token) {
        try {
            //删除token
            tokenService.delToken(token);
            //注销成功
            return DtoUtil.returnSuccess();
        } catch (Exception e) {
            e.printStackTrace();
            return DtoUtil.returnFail("注销失败 ", ErrorCode.AUTH_UNKNOWN);
        }
    }
}
